from django.utils.translation import gettext_lazy, gettext as _
from django.utils.functional import lazy
from drf_yasg import openapi
from rest_framework.permissions import IsAuthenticated
from rest_framework.serializers import Serializer
from rest_framework.response import Response
from rest_framework.decorators import action
from drf_yasg.utils import swagger_auto_schema, no_body

from core import errors
from utils.paginators import NoPaginatorInspector
from utils.lazy_funcs import lazy_str_join
from apps.api.paginations import NewPageNumberPagination100
from apps.api.viewsets import NormalGenericViewSet, serializer_error_msg
from apps.app_tx_meeting import serializers
from apps.app_tx_meeting.models import MeetingUser
from apps.app_tx_meeting.managers import MeetingUserWrapper, MeetingUserManager


class MeetingUserViewSet(NormalGenericViewSet):
    permission_classes = [IsAuthenticated]
    pagination_class = NewPageNumberPagination100
    lookup_field = 'meeting_user_id'

    @swagger_auto_schema(
        tags=['tx_meeting'],
        operation_summary=gettext_lazy('查询用户在会议预定服务中个人的信息和角色'),
        paginator_inspectors=[NoPaginatorInspector],
        responses={
            200: ''''''
        }
    )
    @action(methods=['GET'], detail=False, url_path='personal', url_name='personal-permission')
    def user_personal_permission(self, request, *args, **kwargs):
        """
        查询用户在会议预定服务中个人的信息和角色

            http code 200:
            {
                "id": "g3eecn3m19jkr03u6cb2a48bu",  # meeting user id
                "role": "regular",      # admin(管理员)，regular(普通用户)
                "status": "active",     # active（有效）， inactive(无效)
                "creation_time": "2025-04-24T07:27:12.847990Z",
                "update_time": "2025-04-24T07:27:12.848063Z",
                "user": {
                    "id": "8",      # 全局用户id
                    "username": "xxx@cnic.cn",
                    "fullname": "xx",
                    "telephone": "5881",
                    "company": "cnic"
                }
            }
        """
        ur_wrapper = MeetingUserWrapper(user=request.user)
        obj = ur_wrapper.get_or_create_meeting_user()
        return Response(data=serializers.MeetingUserSerializer(obj).data)

    @swagger_auto_schema(
        tags=['tx_meeting'],
        operation_summary=gettext_lazy('列举会议预定的用户（管理员权限）'),
        manual_parameters=[
            openapi.Parameter(
                name='status',
                in_=openapi.IN_QUERY,
                required=False,
                type=openapi.TYPE_STRING,
                description=lazy_str_join(gettext_lazy('用户状态查询。'), MeetingUser.UserStatus.choices)
            ),
            openapi.Parameter(
                name='role',
                in_=openapi.IN_QUERY,
                required=False,
                type=openapi.TYPE_STRING,
                description=lazy_str_join(gettext_lazy('用户角色查询。'), MeetingUser.Role.choices)
            ),
            openapi.Parameter(
                name='search',
                in_=openapi.IN_QUERY,
                required=False,
                type=openapi.TYPE_STRING,
                description=gettext_lazy('用户名检索。')
            ),
        ],
        responses={
            200: ''''''
        }
    )
    def list(self, request, *args, **kwargs):
        """
        列举会议预定的用户，管理员权限

            http code 200:
            {
                "count": 1,
                "page_num": 1,
                "page_size": 100,
                "results": [
                    {
                        "id": "g3eecn3m19jkr03u6cb2a48bu",  # meeting user id
                        "role": "regular",      # admin(管理员)，regular(普通用户)
                        "status": "active",     # active（有效）， inactive(无效)
                        "creation_time": "2025-04-24T07:27:12.847990Z",
                        "update_time": "2025-04-24T07:27:12.848063Z",
                        "user": {
                            "id": "8",      # 全局用户id
                            "username": "xxx@cnic.cn",
                            "fullname": "xx",
                            "telephone": "5881",
                            "company": "cnic"
                        }
                    }
                ]
            }
        """
        status = request.query_params.get('status')
        role = request.query_params.get('role')
        search = request.query_params.get('search')

        if status and status not in MeetingUser.UserStatus.values:
            return self.exception_response(
                errors.InvalidArgument(message=_('用户状态无效')))

        if role and role not in MeetingUser.Role.values:
            return self.exception_response(
                errors.InvalidArgument(message=_('用户角色无效')))

        ur_wrapper = MeetingUserWrapper(user=request.user)
        if not ur_wrapper.is_active_user():
            return self.exception_response(
                errors.AccessDenied(message=_('你的账号状态无效')))

        if not ur_wrapper.is_admin():
            return self.exception_response(
                errors.AccessDenied(message=_('你没有管理员权限')))

        queryset = MeetingUserManager.filter_meeting_user_qs(
            status=status, role=role, search=search
        )

        page = self.paginate_queryset(queryset)
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)

    @swagger_auto_schema(
        tags=['tx_meeting'],
        operation_summary=gettext_lazy('修改会议预定的用户角色（管理员权限）'),
        request_body=no_body,
        manual_parameters=[
            openapi.Parameter(
                name='role',
                in_=openapi.IN_QUERY,
                type=openapi.TYPE_STRING,
                required=True,
                description=lazy(str, str)(MeetingUser.Role.choices)
            )
        ],
        responses={
            200: ''''''
        }
    )
    @action(methods=['POST'], detail=True, url_path='role', url_name='role')
    def set_user_role(self, request, *args, **kwargs):
        """
        修改会议预定的用户角色，管理员权限

            http code 200:
            {
                "role": "regular",
            }
        """
        role = request.query_params.get('role', None)
        if not role:
            return self.exception_response(
                errors.InvalidArgument(message=_('必须指定角色')))

        if role not in MeetingUser.Role.values:
            return self.exception_response(
                errors.InvalidArgument(message=_('角色无效')))

        auth_user = MeetingUserWrapper(user=request.user)
        if not auth_user.is_active_user():
            return self.exception_response(
                errors.AccessDenied(message=_('你的账号状态无效')))

        if not auth_user.is_admin():
            return self.exception_response(
                errors.AccessDenied(message=_('你没有管理员权限')))

        try:
            MeetingUserManager.set_user_role_by_id(meeting_user_id=kwargs[self.lookup_field], role=role)
        except Exception as exc:
            return self.exception_response(exc=exc)

        return Response(data={'role': role})

    @swagger_auto_schema(
        tags=['tx_meeting'],
        operation_summary=gettext_lazy('修改会议预定的用户状态（管理员权限）'),
        request_body=no_body,
        manual_parameters=[
            openapi.Parameter(
                name='status',
                in_=openapi.IN_QUERY,
                type=openapi.TYPE_STRING,
                required=True,
                description=lazy(str, str)(MeetingUser.UserStatus.choices)
            )
        ],
        responses={
            200: ''''''
        }
    )
    @action(methods=['POST'], detail=True, url_path='status', url_name='status')
    def set_user_status(self, request, *args, **kwargs):
        """
        修改会议预定的用户状态，管理员权限

            http code 200:
            {
                "status": "active",
            }
        """
        status = request.query_params.get('status', None)
        if not status:
            return self.exception_response(
                errors.InvalidArgument(message=_('必须指定用户状态')))

        if status not in MeetingUser.UserStatus.values:
            return self.exception_response(
                errors.InvalidArgument(message=_('用户状态无效')))

        auth_user = MeetingUserWrapper(user=request.user)
        if not auth_user.is_active_user():
            return self.exception_response(
                errors.AccessDenied(message=_('你的账号状态无效')))

        if not auth_user.is_admin():
            return self.exception_response(
                errors.AccessDenied(message=_('你没有管理员权限')))

        try:
            MeetingUserManager.set_user_status_by_id(meeting_user_id=kwargs[self.lookup_field], status=status)
        except Exception as exc:
            return self.exception_response(exc=exc)

        return Response(data={'status': status})

    @swagger_auto_schema(
        tags=['tx_meeting'],
        operation_summary=gettext_lazy('会议预定的用户信息修改（用户个人或管理员权限）'),
        paginator_inspectors=[NoPaginatorInspector],
        responses={
            200: ''''''
        }
    )
    def update(self, request, *args, **kwargs):
        """
        会议预定的用户信息修改，用户个人或管理员权限

            http code 200:
            {
                "id": "g3eecn3m19jkr03u6cb2a48bu",  # meeting user id
                "role": "regular",      # admin(管理员)，regular(普通用户)
                "status": "active",     # active（有效）， inactive(无效)
                "creation_time": "2025-04-24T07:27:12.847990Z",
                "update_time": "2025-04-24T07:27:12.848063Z",
                "user": {
                    "id": "8",      # 全局用户id
                    "username": "xxx@cnic.cn",
                    "fullname": "xx",
                    "telephone": "5881",
                    "company": "cnic"
                }
            }
        """

        serializer = self.get_serializer(data=request.data)
        if not serializer.is_valid(raise_exception=False):
            msg = serializer_error_msg(serializer.errors)
            return self.exception_response(exc=errors.InvalidArgument(message=msg))

        ur_wrapper = MeetingUserWrapper(user=request.user)
        if not ur_wrapper.is_active_user():
            return self.exception_response(
                errors.AccessDenied(message=_('你的账号状态无效')))

        # 用户
        meeting_user_id = kwargs['meeting_user_id']
        if not meeting_user_id:
            return self.exception_response(
                errors.InvalidArgument(message=_('请填写有效参数')))

        meeting_user = MeetingUserManager().get_meeting_user_by_id(meeting_user_id=meeting_user_id)
        if not meeting_user:
            return self.exception_response(
                errors.InvalidArgument(message=_('账户不存在')))

        if not ur_wrapper.is_admin() and request.user != meeting_user.user:
            return self.exception_response(
                errors.AccessDenied(message=_('你没有权限修改用户信息')))

        data = serializer.validated_data  # 必填项

        meeting_user.user.telephone = data['telephone']
        meeting_user.user.company = data['company']
        meeting_user.user.first_name = data['first_name']
        meeting_user.user.last_name = data['last_name']

        try:
            meeting_user.user.save(update_fields=['telephone','company', 'first_name', 'last_name'])
        except Exception as e:
            return self.exception_response(
                errors.Error(message=_('修改用户数据时错误。') + str(e)))

        return Response(data=serializers.MeetingUserSerializer(meeting_user).data)

    def get_serializer_class(self):
        if self.action in ['user_personal_permission', 'list']:
            return serializers.MeetingUserSerializer
        elif self.action == 'update':
            return serializers.MeetingUserUpdateSerializer

        return Serializer
